home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 9 / The PC-SIG Library on CD ROM - Ninth Edition.iso / 401_500 / DISK0417 / DISK0417.ZIP / PROLOG.ARC / VISION.ARC / FRAMES.PRO next >
Text File  |  1986-05-26  |  6KB  |  220 lines

  1. .he                           FRAMES.PRO
  2. .pn1
  3.  
  4. /* 
  5.     Title: Frames.pro
  6.     Function: Module 1/3 of Frames System
  7. */
  8.  
  9. /* get the Value of Slot in a given Frame */
  10. frame_get(Frame,Slot,Value) :-
  11.     ffget(Frame,Frame,Slot,Value).
  12.  
  13. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* check for a value Facet */
  14.     fget(Frame,Slot,value,Value).
  15. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* does it have a default? */
  16.     fget(Frame,Slot,default,Value).
  17. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* how about a demon?      */
  18.     fget(Frame,Slot,if_needed,Rule),
  19.     F =.. [Rule,Parameter_Frame,Value],
  20.     F.
  21. ffget(Parameter_Frame,Frame,Slot,Value) :-  /* none of the above */
  22.     fget(Frame,ako,value,Parent),    /* so, move up the hierarchy */
  23.     ffget(Parameter_Frame,Parent,Slot,Value).
  24.  
  25. fget(Frame,Slot,Facet,Value) :-    /* just grab the given Facet or fail */
  26.     F =.. [Frame,Slot,Facet,Value],
  27.     F.
  28.  
  29.  
  30.  
  31. /* put Value in Slot of a given Frame.    If this Slot has an associated
  32.    if_added demon, then grab it and execute it    after  installing the
  33.    given Value.
  34. */
  35. frame_put(Frame,Slot,Value) :-
  36.     get_rule(Frame,Slot,if_added,Rule), /* must we do something extra */
  37.     fput(Frame,Slot,value,Value),
  38.     F =.. [Rule,Frame,Value],         
  39.     F.
  40. frame_put(Frame,Slot,Value) :-
  41.     fput(Frame,Slot,value,Value).        /* just a simple fput will do */
  42.  
  43. fput(Frame,Slot,Facet,Value) :-
  44.     F =.. [Frame,Slot,Facet,Value],
  45.     assertz(F).
  46.  
  47.  
  48.  
  49.  
  50. /* remove Slot from a given Frame.  If the Slot has an associated
  51.    if_removed demon, then grab the rule and execute it    before ,
  52.    removing the Slot.
  53. */
  54. frame_remove(Frame,Slot) :-
  55.     get_rule(Frame,Slot,if_removed,Rule),  /* something extra to do */
  56.     F =.. [Rule,Frame],
  57.     F,
  58.     fremove(Frame,Slot).
  59. frame_remove(Frame,Slot) :-
  60.     fremove(Frame,Slot).       /* just a simple fremove */
  61.  
  62. fremove(Frame,Slot) :-
  63.     F =.. [Frame,Slot,value,Value],
  64.     retract(F).
  65. fremove(_,_).        /* if Slot doesn't exist, then no harm done */
  66.  
  67.  
  68.  
  69.  
  70. /*  replace whatever is in Slot with Value.  If the Slot has an associated 
  71.     if_replaced rule, then grab it and execute it  after  doing the
  72.     replacement.
  73. */
  74. frame_replace(Frame,Slot,Value) :-
  75.     get_rule(Frame,Slot,if_replaced,Rule), /* something extra to do */
  76.     freplace(Frame,Slot,Value),
  77.     F =.. [Rule,Frame],
  78.     F.
  79. frame_replace(Frame,Slot,Value) :-
  80.     freplace(Frame,Slot,Value).           /* just a simple replace */
  81.  
  82. freplace(Frame,Slot,Value) :-
  83.     fremove(Frame,Slot),
  84.     frame_put(Frame,Slot,Value).
  85.  
  86.  
  87.  
  88.  
  89.  
  90. /* append Value to the list in Slot.  If Slot has an associated 
  91.    if_appended rule, then grab it and execute it  after  appending
  92.    the Value.
  93. */
  94. frame_append(Frame,Slot,Value) :-
  95.     get_rule(Frame,Slot,if_appended,Rule),
  96.     fappend(Frame,Slot,Value),
  97.     F =.. [Rule,Frame],
  98.     F.
  99. frame_append(Frame,Slot,Value) :-
  100.     fappend(Frame,Slot,Value).
  101.  
  102.  
  103. /* here we check to see if the slot already exists.  
  104.    If it does, then we just append the new Value to the old value list.  
  105.    If the Slot does not exist, then we create it and give it a value 
  106.    consisting of the list whose single element is Value.
  107. */
  108. fappend(Frame,Slot,Value) :-
  109.     fget(Frame,Slot,value,Old),
  110.     (member(Value,Old)
  111.     ;
  112.      fremove(Frame,Slot),
  113.      fput(Frame,Slot,value,[Value|Old])
  114.     ).
  115. fappend(Frame,Slot,Value) :-
  116.     fput(Frame,Slot,value,[Value]).
  117.  
  118.  
  119. /* this is a simple utility predicate used to travel up the frame
  120.    hierarchy looking for an appropriate rule to grab.
  121. */
  122. get_rule(Frame,Slot,Type,Rule) :-
  123.     fget(Frame,Slot,Type,Rule).
  124. get_rule(Frame,Slot,Type,Rule) :-
  125.     fget(Frame,ako,value,Parent),
  126.     get_rule(Parent,Slot,Type,Rule).
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133. /*  Example 
  134.  
  135. frame representation:
  136.  
  137.      cylinder
  138.       ako
  139.            value : thing
  140.       height
  141.            if_added : cylinder_height_add
  142.            if_removed : cylinder_height_remove
  143.       radius
  144.            if_added : cylinder_radius_add
  145.            If_removed : cylinder_radius_remove
  146.       cross_section
  147.            if_needed : cylinder_cross_section
  148.       volume
  149.            if_needed : cylinder_volume
  150.       
  151.      cylinder1
  152.       ako
  153.            value : cylinder
  154.  
  155.  
  156. comments:  cylinder1  above is an instance of cylinder.   When we 
  157. use frame_put(cylinder1,radius,2),  say,  the system will install 
  158. the  number  "2" as the value of cylinder1's radius and  it  will 
  159. further  compute cylinder1's cross sectional area and install  it 
  160. under the cross_section slot.  Similar actions take place when we 
  161. do a frame_put for cylinder1's height.   Below is the Prolog code 
  162. that implements all this.  NOTE: PDPROLOG only supports integer
  163. arithmetic.
  164. */
  165.  
  166.  
  167. cylinder(ako,value,geometric_object).
  168. cylinder(height,if_added,cylinder_height_add).
  169. cylinder(height,if_removed,cylinder_height_remove).
  170. cylinder(radius,if_added,cylinder_radius_add).
  171. cylinder(radius,if_removed,cylinder_radius_remove).
  172. cylinder(cross_section,if_needed,cylinder_cross_section).
  173. cylinder(volume,if_needed,cylinder_volume).
  174.  
  175. /* if we get the height, then we try to compute the cylinder's
  176.    volume.
  177. */
  178. cylinder_height_add(Cylinder,_) :-
  179.     cylinder_volume(Cylinder,_).
  180. cylinder_height_add(_,_).    /* if we can't do it, 
  181.                  e.g., the radius is unknown, 
  182.                  then no harm done */
  183.  
  184. /* if the height is removed, then the old volume is no 
  185.    longer valid 
  186. */
  187. cylinder_height_remove(Cylinder) :-
  188.     frame_remove(Cylinder,volume).
  189.  
  190. /* if we get the radius, then we can compute the cylinder's
  191.    cross sectional area
  192. */
  193. cylinder_radius_add(Cylinder,_) :-
  194.     cylinder_cross_section(Cylinder,_).
  195.  
  196. /* if the radius is removed, then the old cross sectional area
  197.    is no longer valid
  198. */
  199. cylinder_radius_remove(Cylinder) :-
  200.     frame_remove(Cylinder,cross_section),
  201.     frame_remove(cylinder,volume).
  202.  
  203. /* PDPROLOG does not support floating-point arithmetic, so pi has been
  204.    approximated as 3.  If you are using a commercial prolog, change 3 to 3.1416
  205. */
  206. cylinder_cross_section(Cylinder,Cross_Section) :-
  207.     frame_get(Cylinder,radius,Radius),
  208.     Cross_Section is 3*Radius*Radius,
  209.     freplace(Cylinder,cross_section,Cross_Section).
  210.  
  211. cylinder_volume(Cylinder,Volume) :-
  212.     frame_get(Cylinder,cross_section,Cross_Section),
  213.     frame_get(Cylinder,height,Height),
  214.     Volume is Height*Cross_Section,
  215.     freplace(Cylinder,volume,Volume).
  216.  
  217. cylinder1(ako,value,cylinder).
  218.  
  219.  
  220.